home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1995 October / EnigmA AMIGA RUN 01 (1995)(G.R. Edizioni)(IT)[!][issue 1995-10][Aminet 7].iso / Aminet / mus / misc / maplay1_2.lha / maplay / ibitstream.cc < prev    next >
C/C++ Source or Header  |  1994-06-23  |  5KB  |  218 lines

  1. /*
  2.  *  @(#) ibitstream.cc 1.8, last edit: 6/15/94 16:51:45
  3.  *  @(#) Copyright (C) 1993, 1994 Tobias Bading (bading@cs.tu-berlin.de)
  4.  *  @(#) Berlin University of Technology
  5.  *
  6.  *  This program is free software; you can redistribute it and/or modify
  7.  *  it under the terms of the GNU General Public License as published by
  8.  *  the Free Software Foundation; either version 2 of the License, or
  9.  *  (at your option) any later version.
  10.  *
  11.  *  This program is distributed in the hope that it will be useful,
  12.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  *  GNU General Public License for more details.
  15.  *
  16.  *  You should have received a copy of the GNU General Public License
  17.  *  along with this program; if not, write to the Free Software
  18.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  */
  20.  
  21. /*
  22.  *  Changes from version 1.1 to 1.2:
  23.  *    - third argument in open syscall added
  24.  *    - minor bug in get_header() fixed
  25.  */
  26.  
  27. #include <stdio.h>
  28. #include <stdlib.h>
  29. #include <unistd.h>
  30. #include <errno.h>
  31. #include <fcntl.h>
  32. #include <iostream.h>
  33. #include "all.h"
  34. #include "ibitstream.h"
  35.  
  36.  
  37. #define swap_int32(int_32) (((int_32) << 24) | (((int_32) << 8) & 0x00ff0000) | \
  38.                (((int_32) >> 8) & 0x0000ff00) | ((int_32) >> 24))
  39.  
  40.  
  41. Ibitstream::Ibitstream (int filedescriptor)        // constructor
  42. {
  43.   fd = filedescriptor;
  44.   wordpointer = buffer;
  45.   bitindex = 0;
  46. }
  47.  
  48.  
  49. Ibitstream::Ibitstream (const char *filename)        // constructor
  50. {
  51.   if ((fd = open (filename, O_RDONLY, 0)) < 0)
  52.   {
  53.     cerr << "can't open file \"" << filename << "\" for reading!\n";
  54.     exit (1);
  55.   }
  56.   wordpointer = buffer;
  57.   bitindex = 0;
  58. }
  59.  
  60.  
  61. Ibitstream::~Ibitstream (void)                // destructor
  62. {
  63.   close (fd);
  64. }
  65.  
  66.  
  67. bool Ibitstream::get_header (uint32 *headerstring)
  68. {
  69.   int readvalue;
  70.  
  71.   if ((readvalue = read (fd, (char *)headerstring, 4)) != 4)
  72.   {
  73.     if (readvalue < 0)
  74.     {
  75.       perror ("read");
  76.       exit (1);
  77.     }
  78.     else if (!readvalue)
  79.       return False;        // EOF
  80.     // header has not been read completely (this may happen while using a pipe)
  81.     int length = 4 - readvalue;
  82.     char *buffer_pos = (char *)headerstring;
  83.     do
  84.     {
  85.       buffer_pos += readvalue;
  86.       readvalue = read (fd, buffer_pos, length);
  87.       if (readvalue < 0)
  88.       {
  89.     perror ("read");
  90.     exit (1);
  91.       }
  92.       else if (!readvalue)
  93.     return False;
  94.     }
  95.     while (length -= readvalue);
  96.   }
  97. #ifdef DAMN_INTEL_BYTE_ORDER
  98.   register uint32 header = *headerstring;
  99.   *headerstring = swap_int32 (header);
  100. #endif
  101.   return True;
  102. }
  103.  
  104.  
  105. bool Ibitstream::read_frame (uint32 bytesize)
  106. {
  107.   int readvalue;
  108.  
  109.   if (bytesize > (bufferintsize << 2))
  110.   {
  111.     cerr << "Internal error: framelength > bufferlength?!\n";
  112.     exit (1);
  113.   }
  114.  
  115.   if ((readvalue = read (fd, (char *)buffer, bytesize)) != bytesize)
  116.   {
  117.     if (readvalue < 0)
  118.     {
  119.       perror ("read");
  120.       exit (1);
  121.     }
  122.     else if (!readvalue)
  123.       return False;        // EOF
  124.     // frame has not been read completely (this may happen while using a pipe)
  125.     int length = bytesize - readvalue;
  126.     char *buffer_pos = (char *)buffer;
  127.     do
  128.     {
  129.       buffer_pos += readvalue;
  130.       readvalue = read (fd, buffer_pos, length);
  131.       if (readvalue < 0)
  132.       {
  133.     perror ("read");
  134.     exit (1);
  135.       }
  136.       else if (!readvalue)
  137.     return False;
  138.     }
  139.     while (length -= readvalue);
  140.   }
  141.  
  142.   wordpointer = buffer;
  143.   bitindex = 0;
  144.   framesize = bytesize;
  145. #ifdef DAMN_INTEL_BYTE_ORDER
  146.   register uint32 *wordp, word;
  147.   for (wordp = buffer + ((bytesize - 1) >> 2); wordp >= buffer; --wordp)
  148.   {
  149.     word = *wordp;
  150.     *wordp = swap_int32 (word);
  151.   }
  152. #endif
  153.   return True;
  154. }
  155.  
  156.  
  157. uint32 Ibitstream::get_bits (uint32 number_of_bits)
  158. {
  159.   static uint32 bitmask[17] =
  160.   {
  161.     0,    // dummy
  162.     0x00000001, 0x00000003, 0x00000007, 0x0000000F,
  163.     0x0000001F, 0x0000003F, 0x0000007F, 0x000000FF,
  164.     0x000001FF, 0x000003FF, 0x000007FF, 0x00000FFF,
  165.     0x00001FFF, 0x00003FFF, 0x00007FFF, 0x0000FFFF
  166.   };
  167.   uint32 returnvalue;
  168.   uint32 sum = bitindex + number_of_bits;
  169.  
  170. #ifdef DEBUG
  171.   if (number_of_bits < 1 || number_of_bits > 16)
  172.   {
  173.     cerr << "illegal parameter in Ibitstream::get_bits() !\n";
  174.     exit (1);
  175.   }
  176. #endif
  177.  
  178.   if (sum <= 32)
  179.   {
  180.     // all bits contained in *wordpointer
  181.     returnvalue = (*wordpointer >> (32 - sum)) & bitmask[number_of_bits];
  182.     if ((bitindex += number_of_bits) == 32)
  183.     {
  184.       bitindex = 0;
  185.       if ((char *)++wordpointer > (char *)buffer + framesize)
  186.       {
  187.     cerr << "Ibitstream::get_bits(): no more bits in buffer!\n";
  188.     exit (1);
  189.       }
  190.     }
  191.     return returnvalue;
  192.   }
  193.  
  194.   // bits are in *wordpointer and *(wordpointer + 1)
  195.   // bitindex has to be > 16
  196. #ifndef DAMN_INTEL_BYTE_ORDER
  197.   *(int16 *)&returnvalue = *((int16 *)wordpointer + 1);
  198.   if ((char *)++wordpointer > (char *)buffer + framesize)
  199.   {
  200.     cerr << "Ibitstream::get_bits(): no more bits in buffer!\n";
  201.     exit (1);
  202.   }
  203.   *((int16 *)&returnvalue + 1) = *(int16 *)wordpointer;
  204. #else
  205.   *((int16 *)&returnvalue + 1) = *(int16 *)wordpointer;
  206.   if ((char *)++wordpointer > (char *)buffer + framesize)
  207.   {
  208.     cerr << "Ibitstream::get_bits(): no more bits in buffer!\n";
  209.     exit (1);
  210.   }
  211.   *(int16 *)&returnvalue = *((int16 *)wordpointer + 1);
  212. #endif
  213.   returnvalue >>= 48 - sum;    // returnvalue >>= 16 - (number_of_bits - (32 - bitindex))
  214.   returnvalue &= bitmask[number_of_bits];
  215.   bitindex = sum - 32;
  216.   return returnvalue;
  217. }
  218.